package org.ttitfly.workflow.engine;

import java.util.List;

import org.ttitfly.workflow.exception.ProcessRunException;
import org.ttitfly.workflow.handler.Handler;
import org.ttitfly.workflow.handler.ListHandlerInvocation;


/**
 * 任务执行类运行单元，任务含有三个状态：就绪(<code>READY</code>)运行( <code>RUNNING</code>)和关闭(
 * <code>CLOSED</code> )。当一个任务被调度之后立即处于就绪(<code>READY</code> )状态，此时立即进行初始化，紧接着调用
 * {@link #active()} 方法进行激活，激活后则处于运行( <code>RUNNING</code>
 * )状态，同时，若含有激活处理程序则会实例化一个处理程序调用链进行调用。运行完毕后则处于关闭( <code>CLOSED</code>
 * )状态同时，若含有关闭处理程序则会实例化一个处理程序调用链进行调用。运行完毕后如果还有后续运行单元则触发调度方调度后续运行单元，至此，
 * 一个任务的生命周期结束。
 * 
 * <p>
 * 注意：任务的实例应由调度方负责检查控制，若不，请确认是否允许同一任务的多个实例处于<code>运行(RUNNING)</code>状态。
 * </p>
 * 
 * <p>
 * 子类通过覆盖#onActive()和#onClosed()方法来实现一些扩展功能
 * </p>
 * 
 * @author 潘海春
 * @version 2009-9-11
 */
public abstract class AbstractRunUnit implements RunUnit {

	/**
	 * 就绪状态
	 */
	public static int READY = 1;

	/**
	 * 运行状态
	 */
	public static int RUNNING = 2;

	/**
	 * 关闭状态
	 */
	public static int CLOSED = 3;

	/**
	 * 名字
	 */
	private String name;

	/**
	 * 激活处理程序
	 */
	private List<Handler> activeHandlers;

	/**
	 * 关闭处理程序
	 */
	private List<Handler> closeHandlers;

	/**
	 * 构造函数
	 * 
	 * @param name
	 * @param activeHandlers
	 * @param closeHandlers
	 */
	public AbstractRunUnit(String name, List<Handler> activeHandlers,
			List<Handler> closeHandlers) {
		if (name == null || "".equals(name = name.trim())) {
			throw new IllegalArgumentException("参数[name]不能为空！");
		}
		this.name = name;
		this.activeHandlers = activeHandlers;
		this.closeHandlers = closeHandlers;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public void run() throws ProcessRunException {
		init();
		active();
	}

	/**
	 * 初始化
	 */
	protected void init() throws ProcessRunException {
		try {
			onInit();
			setStatus(READY);
		} catch (Exception e) {
			throw new ProcessRunException(e);
		}
	}

	/**
	 * 初始化时做的事情，默认什么都不做，如果子类需要处理一些事情，应该覆盖此方法
	 * 
	 * @throws Exception
	 */
	protected void onInit() throws Exception {

	}

	/**
	 * 激活
	 * 
	 * @throws ProcessRunException
	 */
	protected void active() throws ProcessRunException {
		if (!isReady()) {
			throw new ProcessRunException("当前状态必须为'READY'才能进行此操作！");
		}
		setStatus(RUNNING);
		try {
			if (activeHandlers != null) {
				new ListHandlerInvocation(activeHandlers).proceed();
			}
			onActive();
		} catch (Exception e) {
			throw new ProcessRunException(e);
		}
	}

	/**
	 * 激活时做的事情，默认什么都不做，如果子类需要处理一些事情，应该覆盖此方法
	 * 
	 * @throws Exception
	 */
	protected void onActive() throws Exception {

	}

	/**
	 * 关闭
	 * 
	 * @throws ProcessRunException
	 */
	protected void close() throws ProcessRunException {
		if (!isRunning()) {
			throw new ProcessRunException("当前状态必须为'RUNNING'才能进行此操作！");
		}
		setStatus(CLOSED);
		try {
			if (closeHandlers != null) {
				new ListHandlerInvocation(closeHandlers).proceed();
			}
			onClose();
		} catch (Exception e) {
			throw new ProcessRunException(e);
		}
	}

	/**
	 * 关闭时做的事情，默认什么都不做，如果子类需要处理一些事情，应该覆盖此方法
	 * 
	 * @throws Exception
	 */
	protected void onClose() throws Exception {

	}

	/**
	 * 如果status值是就绪(<code>READY</code>)返回<code>true</code>，否则返回
	 * <code>false</code>
	 * 
	 * @return
	 */
	protected boolean isReady() {
		return getStatus() == READY;
	}

	/**
	 * 如果status值是运行(<code>RUNNING</code>)返回<code>true</code>，否则返回
	 * <code>false</code>
	 * 
	 * @return
	 */
	protected boolean isRunning() {
		return getStatus() == RUNNING;
	}

	/**
	 * 如果status值是关闭(<code>CLOSED</code>)返回<code>true</code>，否则返回
	 * <code>false</code>
	 */
	protected boolean isClosed() {
		return getStatus() == CLOSED;
	}

	/**
	 * 获取状态
	 * 
	 * @return
	 */
	protected abstract int getStatus();

	/**
	 * 设置状态
	 * 
	 * @param status
	 */
	protected abstract void setStatus(int status);

}
